<!DOCTYPE html>
<html lang="en">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Porting to GCC 11</title>
<link rel="stylesheet" type="text/css" href="https://gcc.gnu.org/gcc.css" />
</head>

<body>
<h1>Porting to GCC 11</h1>

<p>
The GCC 11 release series differs from previous GCC releases in
<a href="changes.html">a number of ways</a>. Some of these are a result
of bug fixing, and some old behaviors have been intentionally changed
to support new standards, or relaxed in standards-conforming ways to
facilitate compilation or run-time performance.
</p>

<p>
Some of these changes are user visible and can cause grief when
porting to GCC 11. This document is an effort to identify common issues
and provide solutions. Let us know if you have suggestions for improvements!
</p>


<!--
<h2 id="cpp">Preprocessor issues</h2>
<h2 id="c">C language issues</h2>
-->

<h2 id="cxx">C++ language issues</h2>

<h3 id="gxx17">Default standard is now GNU++17</h3>

<p>
GCC 11 defaults to <code>-std=gnu++17</code> instead of <code>-std=gnu++14</code>:
the C++17 standard, plus GNU extensions.
This brings several changes that users should be aware of.  The following
paragraphs describe some of these changes and suggest how to deal with them.
</p>

<p>Some users might prefer to stay with gnu++14, in which case we suggest to
use the <code>-std=gnu++14</code> command-line option, perhaps by putting it
in <code>CXXFLAGS</code> or similar variables in Makefiles.</p>

<h3 id="template-template-changes">Template template parameter matching changes</h3>
<p>G++, starting with
<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=31bfc9b9">G++ 7</a>,
implements C++17
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0522r0.html">P0522R0</a>,
Matching of template template-arguments excludes compatible templates.  As a
consequence, the following test is now rejected:</p>
<pre><code>
    template &lt;int N, int M = N&gt; class A;
    template &lt;int N, int M&gt; void fn(A&lt;N, M&gt; &amp;) {}
    template &lt;int N, template &lt;int&gt; class TT&gt; void fn(TT&lt;N&gt; &amp;);
    template void fn(A&lt;3&gt; &amp;);
</code></pre>

<p>because <code>A</code> is now considered a valid argument for <code>TT</code>,
so both function templates are valid candidates, and neither is more specialized
than the other, so it's ambiguous.</p>

<p>The new behavior can be disabled independently of other C++17 features with
<code>-fno-new-ttp-matching</code>.</p>

<h3 id="Ordered-pointer-comparison-with-integer">Ordered pointer comparison with integer</h3>
<p>
GCC 11 now issues a diagnostic for ordered comparisons of pointers against constant
integers.  Commonly this is an ordered comparison against NULL or 0.  These should be
equality comparisons, not ordered comparisons.
</p>

<h3 id="Dynamic-Exception-Specifications">Dynamic Exception Specifications</h3>
<p>
GCC 11 defaults to C++17 which does not allow dynamic exception specifications.
</p>
<p>
An exception specification like <code>throw(std::runtime_error)</code> should
be removed or replaced with <code>noexcept(false)</code> (meaning the function
can throw any type of exception).
An exception specification like <code>throw()</code> can be replaced with
<code>noexcept</code> or <code>noexcept(true)</code> (meaning the function
does not throw exceptions).
</p>

<h3 id="Comparison-Functions">Comparison Functions</h3>
<p>
GCC 11 now enforces that comparison objects be invocable as const.
</p>

<h3 id="header-dep-changes">Header dependency changes</h3>
<p>Some C++ Standard Library headers have been changed to no longer include
other headers that were being used internally by the library.
As such, C++ programs that used standard library components without
including the right headers will no longer compile.
</p>
<p>
The following headers are used less widely in libstdc++ and may need to
be included explicitly when compiled with GCC 11:
</p>
<ul>
<li> <code>&lt;limits&gt;</code>
  (for <code>std::numeric_limits</code>)
</li>
<li> <code>&lt;memory&gt;</code>
  (for <code>std::unique_ptr</code>, <code>std::shared_ptr</code> etc.)
</li>
<li> <code>&lt;utility&gt;</code>
  (for <code>std::pair</code>, <code>std::tuple_size</code>,
  <code>std::index_sequence</code> etc.)
</li>
<li> <code>&lt;thread&gt;</code>
  (for members of namespace <code>std::this_thread</code>.)
</li>
</ul>

<h3 id="Old-iostream-Members">Old iostream Members</h3>
<p>
The deprecated iostream members <code>ios_base::io_state</code>,
<code>ios_base::open_mode</code>, <code>ios_base::seek_dir</code>, and
<code>basic_streambuf::stossc</code> are not available in C++17 mode.
References to those members should be replaced by <code>std::iostate</code>,
<code>std::openmode</code>, <code>std::seekdir</code>, and
<code>basic_streambuf::sbumpc</code> respectively.
</p>

<h3 id="tr1-bind">Call of overloaded <code>'bind(...)'</code> is ambiguous</h3>
<p>
The placeholders for <code>std::tr1::bind</code> have been changed to use
the same placeholder objects as <code>std::bind</code>.  This means that
following <code>using std::tr1::bind;</code> an unqualified call to
<code>bind(f, std::tr1::placeholders::_1)</code> may be ambiguous.
This happens because <code>std::tr1::bind</code> is brought into scope by
the using-declaration and <code>std::bind</code> is found by
Argument-Dependent Lookup due to the type of the <code>_1</code> placeholder.
</p>
<p>
To resolve this ambiguity replace unqualified calls to <code>bind</code>
with <code>std::tr1::bind</code> or <code>std::bind</code>. Alternatively,
change the code to not include the <code>&lt;tr1/functional&gt;</code> header,
so that only <code>std::bind</code> is declared.
</p>

<h3 id="enable-threads">Enable multithreading to use std::thread</h3>
<p>
Programs must be linked to libpthread in order for <code>std::thread</code>
to create new threads of execution.
It is not sufficient to use <code>dlopen</code> to dynamically load
<code>libpthread.so</code> at run-time.
</p>

<h3 id="strict-ansi">Do not undefine <code>__STRICT_ANSI__</code></h3>
<p>
The <code>__STRICT_ANSI__</code> macro is defined by the compiler to
inform the C and C++ standard library headers when a strict language dialect
is being used, e.g. <code>-std=c++17</code> or <code>-std=c11</code> rather
than <code>-std=gnu++17</code> or <code>-std=gnu11</code>.
</p>
<p>
If you undefine the <code>__STRICT_ANSI__</code> macro then you create an
inconsistent state where the compiler is using a strict dialect but the
standard library headers think that GNU extensions are enabled.
The libstdc++ headers in GCC 11 cannot be used in this state and are likely
to produce compilation errors.
</p>
<p>
If you don't want the macro to be defined, don't use a <code>-std</code>
option that causes it to be defined.
Simply use a <code>-std=gnu++<em>NN</em></code> option instead of
<code>-std=c++<em>NN</em></code>.
</p>

<!--
<h2 id="fortran">Fortran language issues</h2>
-->

<!--
<h2 id="links">Links</h2>
-->

</body>
</html>
